package utilityTools;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Geometry;

import java.io.*;

public class GeoJsonUtiles {

    public static JSONObject getGeoJsonSource(File filein) throws IOException {
        FileInputStream fileis = new FileInputStream(filein);
        // 防止路径乱码   如果utf-8 乱码  改GBK eclipse里创建的txt  用UTF-8，在电脑上自己创建的txt  用GBK
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileis, "UTF-8"));
        String line;
        JSONObject geojsonSource;
        //StringBuilder是线程不安全的；而StringBuffer是线程安全的，但是相应的效率会降低
        StringBuilder jsonBuilder = new StringBuilder();
        while ((line = bufferedReader.readLine()) != null) {
            String middleStr = line.replaceAll("\\u00A0+|\\s*|\t|\r|\n", "");
            jsonBuilder.append(middleStr);
        }
        geojsonSource = JSONObject.parseObject(jsonBuilder.toString());//new JSONObject(jsonBuilder.toString());
        return geojsonSource;
    }

    public static JSONObject getGeoJsonSource(String geojsonStr) throws IOException {
        String input = geojsonStr.replaceAll("\\u00A0+|\\s*|\t|\r|\n", "");
        JSONObject geojsonSource = JSONObject.parseObject(input);//new JSONObject(jsonBuilder.toString());
        return geojsonSource;
    }

    /**
     * 将Geometry对象转换为wkt字符串形式
     * @param geometry Geometry对象
     * @return 几何的wkt表示形式
     */
    public static String convertGeometry2Wkt(Geometry geometry){
        GeometryJSON gjFactory = new GeometryJSON();
        String strGeometry= gjFactory.toString(geometry);
        JSONObject jjGeo=JSONObject.parseObject(strGeometry);
        String type= jjGeo.getString("type");
        String coords=jjGeo.getString("coordinates");
        return convertGeometry2Wkt(type,coords);
    }

    /**
     * 将geojson类型表示的Geometry对象转换为wkt表示形式
     * @param jsonObjectGeometry geojson表示的几何对象
     * @return 几何的wkt字符串形式
     */
    public static String convertGeometry2Wkt(JSONObject jsonObjectGeometry){
        String type= jsonObjectGeometry.getString("type");
        String coords=jsonObjectGeometry.getString("coordinates");
        return convertGeometry2Wkt(type,coords);
    }

    /**
     * 创建Geometry的wkt表示形式
     * @param type 几何类型
     * @param coordinates 几何坐标（符合Json格式的坐标字符串）
     * @return 几何的wkt表示形式
     */
    public static String convertGeometry2Wkt(String type, String coordinates) {
        //"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon"
        JSONArray jsonArray = JSONObject.parseArray(coordinates);
        StringBuffer wkt = new StringBuffer();
        type = type.toUpperCase();
        switch (type) {
            case "POINT":
                //[100.0, 0.0]
                wkt.append("POINT(").append(jsonArray.getString(0)).append(" ")
                        .append(jsonArray.getString(1)).append(")");
                break;
            case "MULTIPOINT":
                //[
                //        [100.0, 0.0],
                //        [101.0, 1.0]
                //    ]
                wkt.append("MULTIPOINT(");
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONArray point = jsonArray.getJSONArray(i);
                    wkt.append(point.getString(0)).append(" ").append(point.get(1)).append(",");
                }
                wkt.deleteCharAt(wkt.length() - 1);
                wkt.append(")");
                break;
            case "LINESTRING":
                //和multipoint结构一样
                //[
                //                [101.0, 0.0],
                //                [102.0, 1.0]
                //            ]
                wkt.append("LINESTRING").append(wktLineString(jsonArray));
                break;
            case "MULTILINESTRING":
                //[
                //        [
                //            [100.0, 0.0],
                //            [101.0, 1.0]
                //        ],
                //        [
                //            [102.0, 2.0],
                //            [103.0, 3.0]
                //        ]
                //    ]
                wkt.append("MULTILINESTRING(");
                for (int i = 0; i < jsonArray.size(); i++) {
                    wkt.append("").append(wktLineString(jsonArray.getJSONArray(i))).append("").append(",");
                }
                wkt.deleteCharAt(wkt.length() - 1);
                wkt.append(")");
                break;
            case "POLYGON":
                //POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))
                //"coordinates": [
                //            [
                //                [-180.0, 10.0],
                //                [20.0, 90.0],
                //                [180.0, -5.0],
                //                [-30.0, -90.0]
                //            ]
                //        ]
                wkt.append("POLYGON").append(wktPolygon(jsonArray));
                break;
            case "MULTIPOLYGON":
                //解析为多个polygon
                wkt.append("MULTIPOLYGON(");
                for (int i = 0; i < jsonArray.size(); i++) {
                    wkt.append(wktPolygon(jsonArray.getJSONArray(i))).append(",");
                }
                wkt.deleteCharAt(wkt.length() - 1);
                wkt.append(")");
                break;
        }
        return wkt.toString();
    }

    private static String wktLineString(JSONArray jsonArray) {
        StringBuffer wkt = new StringBuffer();
        wkt.append("(");
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONArray point = jsonArray.getJSONArray(i);
            wkt.append(point.getString(0)).append(" ").append(point.get(1)).append(",");
        }
        wkt.deleteCharAt(wkt.length() - 1);
        wkt.append(")");
        return wkt.toString();
    }

    private static String wktPolygon(JSONArray jsonArray) {
        StringBuffer wkt = new StringBuffer();
        wkt.append("(");
        for (int i = 0; i < jsonArray.size(); i++) {
            //是一组组的LineString
            wkt.append("(");
            JSONArray lineString = jsonArray.getJSONArray(i);
            for (int j = 0; j < lineString.size(); j++) {
                JSONArray pointArray = lineString.getJSONArray(j);
                wkt.append(pointArray.getString(0)).append(" ").append(pointArray.getString(1))
                        .append(",");
            }
            if (wkt.length() > 0) {
                //删除最后一个逗号
                wkt.deleteCharAt(wkt.length() - 1);
            }
            wkt.append("),");
        }
        if (wkt.length() > 0) {
            wkt.deleteCharAt(wkt.length() - 1);
        }
        wkt.append(")");
        return wkt.toString();
    }

}
